AWS JVM CPU限制上的java Docker
我在AWS Fargate服务上的docker容器中启动了spring引导应用程序,因此一旦CPU消耗达到100%以上,容器就会因docker错误而停止
Reason: OutOfMemoryError: Container killed due to memory usage
在指标上,我们可以看到CPU超过100%。貌似经过一段时间的评测之后,我们发现了CPU消耗代码,但我的问题是,CPU怎么能超过100%呢
这是说JVM只使用100%的方式吗
我记得我们在内存消耗方面也有类似的问题。我读了很多关于cgroup的文章,发现解决方案可以指定
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
因此,当您使用选项-m=512启动docker时,堆大小将是mac大小的1/4。堆大小也可以通过选项进行调整
-XX:MaxRAMFraction=2
这将为堆分配1/2的docker内存。 我应该为CPU使用类似的东西吗? 我读了文章https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits,但它告诉我
As of Java SE 8u131, and in JDK 9, the JVM is Docker-aware with respect to Docker CPU limits transparently. That means if -XX:ParalllelGCThreads, or -XX:CICompilerCount are not specified as command line options, the JVM will apply the Docker CPU limit as the number of CPUs the JVM sees on the system. The JVM will then adjust the number of GC threads and JIT compiler threads just like it would as if it were running on a bare metal system with number of CPUs set as the Docker CPU limit.
Docker命令用于启动
docker run -d .... -e JAVA_OPTS='-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+PrintFlagsFinal -XshowSettings:vm' -m=512 -c=256 ...
使用Java版本
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-1~deb9u1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
应用程序启动期间的一些附加信息
VM settings:
Max. Heap Size (Estimated): 123.75M
Ergonomics Machine Class: client
Using VM: OpenJDK 64-Bit Server VM
ParallelGCThreads = 0
CICompilerCount := 2
CICompilerCountPerCPU = true
# 1 楼答案
我找到了我问题的答案。 确定要使用的处理器数量的行为在https://bugs.openjdk.java.net/browse/JDK-8146115中是固定的
因此,在AWS上,您通常在任务定义级别设置cpu共享。 在jvm修复之前,它的计算不正确
关于java8版本<;191:cpu_shares()/1024=256/1024=被标识为2
在java8版本上迁移后>;191:cpu_shares()/1024=256/1024=被标识为1
要测试的代码
样本输出
我希望它能帮助一些人,因为我在任何地方都找不到答案(SpringIssuesTracker、AWS支持等)